package com.example.ftp.Controller.MainWindow;

import com.example.ftp.Beans.Ftp;
import com.example.ftp.Beans.Site;
import com.example.ftp.Controller.MainWindow.FileList.FileItem;
import com.example.ftp.Controller.MainWindow.FileList.FileItemContextMenu;
import com.example.ftp.Controller.SiteManage.SiteList;
import com.example.ftp.Service.FtpService;
import com.example.ftp.Service.Impl.FtpServiceImpl;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import org.apache.commons.net.ftp.FTPFile;

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;

/**
 * 主窗口
 *
 * @author 吴博维
 */
public class MainWindow implements Initializable {

    // 当前窗口实例
    private static BorderPane mainWindow = null;

    // 当前窗口的控制器实例
    private static MainWindow controller = null;

    // 当前选中的文件项
    private static FileItem selectedFileItem;

    // 快速连接
//    @FXML
//    private MenuItem quickConnect;

    // 站点管理
    @FXML
    private MenuItem siteManager;

    // 新建站点
//    @FXML
//    private MenuItem newSite;

    // 文件列表表头
    private static final String[] fileListHeader = new String[]{"name", "type", "size", "date"};

    // 文件列表窗口
    @FXML
    private TableView<FileItem> fileList;

    // 文件列表中的项目
    private final ObservableList<FileItem> fileItems = FXCollections.observableArrayList();

    // 当前任务状态列表
    @FXML
    private TableView<FileItem> statusList;

    private FtpService ftpService;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        path = new SimpleStringProperty();
        pathField.textProperty().bindBidirectional(path);

        initTopMenu();
    }

    // 当前路径
    private SimpleStringProperty path;

    @FXML
    private TextField pathField;

    /**
     * 初始化文件列表
     */
    protected void initFileList() {
        for (int i = 0; i < fileListHeader.length; i ++) {
            fileList.getColumns().get(i).setCellValueFactory(new PropertyValueFactory<>(fileListHeader[i]));
        }

        // 列表内容
        fileList.setItems(fileItems);

        // 设置行
        fileList.setRowFactory(t -> {
            // 上下文菜单
            TableRow<FileItem> row = new TableRow<>();
            FileItemContextMenu contextMenu = new FileItemContextMenu();
            row.setContextMenu(contextMenu);

            // 监听点击事件
            row.setOnMouseClicked(e -> {
                MainWindow.setSelectedFileItem(row.getItem());
                if (row.getItem() == null) {
                    return;
                }
                else if (row.getItem().getName().equals("Upper/") &&
                        e.getClickCount() == 2 && e.getButton().name().equals("PRIMARY")) {
                    try {
                        ftpService.getFtpClient().changeToParentDirectory();
                        try {
                            path.setValue(ftpService.getFtpClient().printWorkingDirectory());
                        } catch (IOException ex) {
                            ex.printStackTrace();
                        }
                        updateFileList();
                    } catch (IOException ex) {
                        ex.printStackTrace();
                        System.out.println("切换到父级目录失败");
                    }
                }
                else if (row.getItem().isDir()) {
                    if(e.getClickCount() == 2 && e.getButton().name().equals("PRIMARY")){
                        path.setValue(path.getValue() + row.getItem().getName() + "/");
                        updateFileList();
                    }
                }
            });
            return row;
        });
    }

    /**
     * 初始化顶部菜单栏
     */
    protected void initTopMenu() {
        siteManager.setOnAction(e -> {
            try {
                SiteList.showSiteList();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        });
    }

    /**
     * 获取主窗口的 UI 实例
     * @return 成功加载返回 UI 实例，反之返回 null
     */
    public static BorderPane getUIInstance() {
        if (mainWindow == null) {
            initWindow();
        }
        return mainWindow;
    }

    /**
     * 获取主窗口的控制器实例
     * @return 返回当前正在运行的窗口的控制器实例
     */
    public static MainWindow getControllerInstance() {
        if (controller == null) {
            initWindow();
        }
        return controller;
    }

    /**
     * 初始化窗口
     */
    private static void initWindow() {
        try {
            // 加载主窗口及控制器
            FXMLLoader windowLoader = new FXMLLoader(MainWindow.class.getResource("main-window.fxml"));
            mainWindow = windowLoader.load();
            controller = windowLoader.getController();
            controller.initFileList();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 连接站点
     * @param site 站点
     */
    public void connectSite(Site site) {
        Ftp ftp = new Ftp();
        ftp.setHost(site.getIp());
        ftp.setPort(site.getPort());
        ftp.setUserName(site.getUserName());
        ftp.setPassword(site.getPassword());

        ftpService = new FtpServiceImpl(ftp);

        if (ftpService.getFtpClient() == null) {
            alert("Failed to connect " + site.getIp() + "!");
        }
        else {
            path.setValue("/");
            updateFileList();
        }
    }

    /**
     * 警告窗口
     * @param string 警告信息
     */
    public void alert(String string) {
        Alert a = new Alert(Alert.AlertType.INFORMATION);
        a.setTitle("Notice");
        a.setContentText(string);
        a.setHeaderText("Notice");
        a.showAndWait();
    }

    /**
     * 更新文件列表
     */
    public void updateFileList() {
        fileItems.clear();
        FileItem upper = new FileItem("Upper/","","",0,true);
        fileItems.add(upper);
        FTPFile[] fs = ftpService.listFiles(path.getValue());
        for (FTPFile f : fs) {
            fileItems.add(new FileItem(f));
        }
    }

    /**
     * 重命名文件
     * @param newName 新的名字
     */
    public void renameFile(String newName) {
        try {
            ftpService.replaceName(path.getValue() + getSelectedFileItem().getName(), path.getValue() + newName);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 下载文件
     * @param localPath 本地路径
     */
    public void downloadFile(String localPath) {
        ftpService.downloadFile(path.getValue() + getSelectedFileItem().getName(), localPath);
    }

    /**
     * 上传文件
     * @param localPath 本地路径
     */
    public void uploadFile(String localPath) {
        try {
            ftpService.upload(path.getValue(), localPath, true, true);
            updateFileList();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void mkdir(String name) {
        try {
            ftpService.makeDirectory(path.getValue() + name);
            updateFileList();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void deleteFile() {
        ftpService.deleteFile(path.getValue() + getSelectedFileItem().getName());
        updateFileList();
    }

    /**
     * Getter and Setter
     */
    public TableView<FileItem> getFileList() {
        return fileList;
    }

    public TableView<FileItem> getStatusList() {
        return statusList;
    }

    public static FileItem getSelectedFileItem() {
        return selectedFileItem;
    }

    public static void setSelectedFileItem(FileItem selectedFileItem) {
        MainWindow.selectedFileItem = selectedFileItem;
    }

    public String getPath() {
        return path.get();
    }

    public SimpleStringProperty pathProperty() {
        return path;
    }

    public void setPath(String path) {
        this.path.set(path);
    }

}
